﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using KillBill.Presentarion.Common.Printing.Reports;

namespace KillBill.Presentarion.Common.Printing.Invoice
{
    public class InvoicePrinter
    {
        public bool NotaDeVenta { get; set; }
        private PrintDocument _factura;
        private Dictionary<string, string> _clientInformation;
        private DataTable _detail;
        private double _subtotal;
        private double _iva;
        private double _ice;
        private double _total;
        private int _page;
        private int[] _size;
        private int[] _columnPositions;
        public int PrintDocument(int startNumber, DataTable information, Dictionary<string, string> clientInformation, int[] size, bool notaDeVenta, double subtotal, double iva, double ice, double total)
        {
            _size = size;
            if (_size.Length != information.Columns.Count)
                return -1;
            _columnPositions = new int[size.Length];
            NotaDeVenta = notaDeVenta;
            _page = startNumber;
            _detail = information;
            _clientInformation = clientInformation;
            _subtotal = subtotal;
            _iva = iva;
            _ice = ice;
            _total = total;
            _factura = new PrintDocument();
            _factura.PrintPage += FacturaPrintPage;
            _factura.Print();
            return _page;
        }
        private void CalculatePositions(PrintPageEventArgs ev)
        {
            int total = 0;
            foreach (int val in _size)
                total += val;
            _columnPositions[0] = ev.MarginBounds.Left;
            for (int i = 1; i < _size.Length; i++)
            {
                _columnPositions[i] = _columnPositions[i - 1] + (_size[i - 1] * (ev.MarginBounds.Width) / total);
            }
        }
        private void FacturaPrintPage(object sender, PrintPageEventArgs ev)
        {
            #region Internal Variables

            string value;
            double Total = 0;
            int auxCounter = 0;
            PointF position = new PointF(ev.MarginBounds.Left, ev.MarginBounds.Top);
            PointF auxPosition = new PointF(position.X, position.Y);
            PointF auxPosition2 = new PointF(position.X, position.Y);
            Font writingFont = new Font("Cambria", 16);
            Pen drawingPen = new Pen(Color.Black, 1);
            string documentName = (NotaDeVenta) ? "Nota de Venta" : "Factura";
            string number = "";
            #endregion

            CalculatePositions(ev);
            #region Company Information
            //Company Name
            ev.Graphics.DrawString((ReportPrinter.CompanyName!=null)?ReportPrinter.CompanyName:"", writingFont, drawingPen.Brush, position);
            position.Y += writingFont.Height;

            //Company Data
            writingFont = new Font("Cambria", 9);
            if(ReportPrinter.CompanyData==null) ReportPrinter.CompanyData=new List<string>();
            foreach (string s in ReportPrinter.CompanyData)
            {
                ev.Graphics.DrawString(s, writingFont, drawingPen.Brush, position);
                position.Y += writingFont.Height;
            }
            auxPosition = position;
            writingFont = new Font("Calibri", 12);
            #endregion
            #region Basic Invoice Information
            //Basic Invoice Information
            position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(documentName, writingFont).Width - 20;
            position.Y = ev.MarginBounds.Top + 10;
            auxPosition2.X = position.X - 20;
            auxPosition2.Y = ev.MarginBounds.Top;
            ev.Graphics.DrawString(documentName, writingFont, drawingPen.Brush, position);
            position.Y += writingFont.Height;
            writingFont = new Font("Calibri", 10);
            number = TextFormater.GetStandardInteger(_page, 6);
            position.X = auxPosition2.X +
                         (ev.MarginBounds.Right - auxPosition2.X - TextRenderer.MeasureText(number, writingFont).Width) /
                         2;
            ev.Graphics.DrawString(number, writingFont, drawingPen.Brush, position);
            ev.Graphics.DrawRectangle(drawingPen, auxPosition2.X, ev.MarginBounds.Top,
                                      ev.MarginBounds.Right - auxPosition2.X,
                                      (position.Y - ev.MarginBounds.Top + 10) + writingFont.Height);
            position.Y += 10 + writingFont.Height;

            position.X = ev.MarginBounds.Left;
            position.Y = (position.Y < auxPosition.Y) ? auxPosition.Y + 40 : position.Y + 40;
            #endregion
            #region Client Information
            auxPosition2 = position;
            foreach (var dictionary in _clientInformation)
            {
                auxCounter++;
                writingFont = new Font("Calibri", 9, FontStyle.Bold);
                auxPosition = position;
                if ((auxCounter % 2) == 0)
                {
                    auxPosition.X += (ev.MarginBounds.Width + 5) / 2;
                    position.Y += writingFont.Height;
                }
                auxPosition.X += 5;
                ev.Graphics.DrawString(dictionary.Key + ": ", writingFont, drawingPen.Brush, auxPosition);
                auxPosition.X += TextRenderer.MeasureText(dictionary.Key + ":_", writingFont).Width;
                writingFont = new Font("Calibri", 9, FontStyle.Italic);
                ev.Graphics.DrawString(dictionary.Value, writingFont, drawingPen.Brush, auxPosition);


            }
            if ((auxCounter % 2) != 0)
                position.Y += writingFont.Height;
            position.Y += writingFont.Height;
            ev.Graphics.DrawRectangle(drawingPen, auxPosition2.X, auxPosition2.Y - 10, ev.MarginBounds.Width,
                                      position.Y - auxPosition2.Y + 10);
            auxCounter = 0;
            position.X = ev.MarginBounds.Left;
            position.Y += 30;
            #endregion

            ev.Graphics.DrawRectangle(drawingPen, position.X, position.Y, ev.MarginBounds.Width,
                                      ev.MarginBounds.Bottom - position.Y - 105);

            foreach (int val in _columnPositions)
                ev.Graphics.DrawLine(drawingPen, val, position.Y, val, ev.MarginBounds.Bottom - 105);

            int i;
            writingFont = new Font("Calibri", 11, FontStyle.Bold | FontStyle.Underline);
            position.Y += 5;
            for (i = 0; i < _detail.Columns.Count; i++)
            {
                position.X = _columnPositions[i] + 5;
                ev.Graphics.DrawString(_detail.Columns[i].Caption, writingFont, drawingPen.Brush, position);
            }
            position.Y += writingFont.Height;
            ev.Graphics.DrawLine(drawingPen, ev.MarginBounds.Left, position.Y, ev.MarginBounds.Right, position.Y);
            position.Y += writingFont.Height;
            writingFont = new Font("Calibri", 10);
            for (i = 0; i < _detail.Rows.Count; i++)
            {
                for (int j = 0; j < _detail.Columns.Count; j++)
                {
                    value = (string) _detail.Rows[i][j];
                    if (j == _detail.Columns.Count - 2)
                    {
                        value = TextFormater.StandardizeNumber(Convert.ToDouble(value), 2, 10).Trim();
                        position.X = _columnPositions[j + 1] - TextRenderer.MeasureText(value, writingFont).Width;
                    }
                    else if (j == _detail.Columns.Count - 1)
                    {
                        value = TextFormater.StandardizeNumber(Convert.ToDouble(value), 2, 10).Trim();
                        position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(value, writingFont).Width;
                    }
                    else
                        position.X = _columnPositions[j] + 5;
                    ev.Graphics.DrawString(value, writingFont, drawingPen.Brush, position);
                }
                position.Y += writingFont.Height;
            }
            position.Y = ev.MarginBounds.Bottom - 100;
            value = "SUBTOTAL:   "+TextFormater.StandardizeNumber(_subtotal, 2, 10).Trim();
            position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(value, writingFont).Width;
            ev.Graphics.DrawString(value, writingFont, drawingPen.Brush, position);
            
            position.Y += writingFont.Height;
            value ="IVA:   "+ TextFormater.StandardizeNumber(_iva, 2, 10).Trim();
            position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(value, writingFont).Width;
            ev.Graphics.DrawString(value, writingFont, drawingPen.Brush, position);

            position.Y += writingFont.Height;
            value = "ICE:   " + TextFormater.StandardizeNumber(_ice, 2, 10).Trim();
            position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(value, writingFont).Width;
            ev.Graphics.DrawString(value, writingFont, drawingPen.Brush, position);

            position.Y += writingFont.Height;
            value ="TOTAL:   "+ TextFormater.StandardizeNumber(_total, 2, 10).Trim();
            position.X = ev.MarginBounds.Right - TextRenderer.MeasureText(value, writingFont).Width;
            ev.Graphics.DrawString(value, writingFont, drawingPen.Brush, position);
        }
    
    }
}
